home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d21 / byload.arc / BYLOAD.C < prev    next >
C/C++ Source or Header  |  1988-09-30  |  5KB  |  170 lines

  1. /******** DESQVIEW/TOPVIEW LOADER FOR BOYAN VERSION D3 ********/
  2.  
  3. /*
  4. **    Written in Turbo C v1.5 small memory model by John Navas.
  5. */
  6.  
  7. char banner[] = "by-load v1.0 " __DATE__ " " __TIME__
  8.     "\r\nCopyright 1988 John Navas II, All Rights Reserved.\r\n";
  9.  
  10. #include <io.h>
  11. #include <dos.h>
  12. #include <mem.h>
  13. #include <process.h>
  14.  
  15. unsigned _heaplen = 512;            /* small heap */
  16. unsigned _stklen = 1024;            /* small stack */
  17.  
  18. #define MONOTXT    7                    /* monochrome text mode */
  19. #define MDASEG    0xB000                /* monochrome video segment */
  20. #define CGASEG    0xB800                /* color video segment */
  21.  
  22. #define RLO(x)    (((unsigned char*)&x)[0])    /* bytes in a word */
  23. #define RHI(x)    (((unsigned char*)&x)[1])
  24.  
  25. typedef    void(interrupt far*INTVEC)();        /* interrupt vector */
  26. typedef    void(interrupt far*far*INTPTR)();    /* interrupt vectors */
  27. #define MKINTPTR(n) (&((INTPTR)0L)[n])        /* make pointer to int vec */
  28.  
  29. #define WR_STRC(f,s)    _write(f,s,sizeof(s)-1)    /* string constant */
  30. #define STDERR    2        /* predefined level 1 file */
  31. #define SE_STRC(s)        WR_STRC(STDERR,s)    /* string con to STDERR */
  32.  
  33. #define BIOSVID        0x10            /* BIOS video interrupt */
  34. #define GETVIDMOD    0x0F                /* get video mode */
  35. #define GETVIDBUF    0xFE                /* get video buffer */
  36.  
  37. #define DOSINT    0x21                /* DOS interrupt number */
  38.  
  39. #define OFFSET    (0x993F-0x9424)        /* offset of patch in overlay */
  40.  
  41. void interrupt (*dosvec)();            /* DOS interrupt vector */
  42. char vidmod;                        /* video mode */
  43. unsigned vidseg;                    /* TopView video buffer segment */
  44. typedef struct {                    /* data structure to patch */
  45.     char a;
  46.     unsigned mda;
  47.     char b[13];
  48.     unsigned cga;
  49. } PATCH;
  50. PATCH pat = {                        /* data pattern to match */
  51.     0xB8,
  52.     MDASEG,
  53.     {
  54.         0xA3, 0x0E, 0x19,
  55.         0xB8, 0x00, 0x00,
  56.         0xA2, 0x41, 0x1B,
  57.         0xE9, 0x15, 0x00,
  58.         0xB8 },
  59.     CGASEG
  60. };
  61. PATCH dat;                            /* patch work area */
  62.  
  63. INTVEC pascal GETVECT(unsigned intnum)                /* GET INT VECTOR */
  64. {
  65.     INTVEC adr;
  66.     disable();
  67.     adr = *MKINTPTR( intnum );
  68.     enable();
  69.     return adr;
  70. }
  71.  
  72. void pascal SETVECT( unsigned intnum, INTVEC adr )    /* SET INT VECTOR */
  73. {
  74.     disable();
  75.     *MKINTPTR( intnum ) = adr;
  76.     enable();
  77. }
  78.  
  79. struct INTREGS {                        /* interrupt routine registers */
  80.     unsigned bp_, di_, si_, ds_, es_, dx_;
  81.     unsigned cx_, bx_, ax_, ip_, cs_, flags_;
  82. };
  83.  
  84. struct INTREGS pascal CHAININT(void (interrupt far *vec)(), struct INTREGS r)
  85. {
  86.     asm    push    ds                ;
  87.     asm    mov        ax,r.ax_        ;
  88.     asm    mov        bx,r.bx_        ;
  89.     asm    mov        cx,r.cx_        ;
  90.     asm    mov        dx,r.dx_        ;
  91.     asm    mov        si,r.si_        ;
  92.     asm    mov        di,r.di_        ;
  93.     asm    mov        ds,r.ds_        ;
  94.     asm    mov        es,r.es_        ;
  95.     asm    pushf                    ;
  96.     asm    cli                        ;
  97.     asm    call    dword ptr[vec]    ;
  98.     asm    pushf                    ;
  99.     asm    mov        r.ax_,ax        ;
  100.     asm    mov        r.bx_,bx        ;
  101.     asm    mov        r.cx_,cx        ;
  102.     asm    mov        r.dx_,dx        ;
  103.     asm    mov        r.si_,si        ;
  104.     asm    mov        r.di_,di        ;
  105.     asm    mov        r.ds_,ds        ;
  106.     asm    mov        r.es_,es        ;
  107.     asm    pop        r.flags_        ;
  108.     asm    pop        ds                ;
  109.     return r;
  110. }
  111.  
  112. void interrupt intentry( struct INTREGS cr )    /* INTERRUPT ENTRY POINT */
  113. {
  114.     struct INTREGS rr;                    /* save entry registers */
  115.     enable();                            /* allow interrupts */
  116.     cr = CHAININT( dosvec, rr = cr );    /* chain to DOS */
  117.     if ( RHI( rr.ax_ ) == 0x3F && rr.cx_ == 0x2200 ) {    /* read overlay */
  118.         dat = *(PATCH far*)MK_FP( rr.ds_, rr.dx_ + OFFSET );
  119.         if ( ! memcmp( (char*)&dat, (char*)&pat, sizeof(pat) ) ) {
  120.             if ( vidmod == MONOTXT )
  121.                 dat.mda = vidseg;            /* monochrome */
  122.             else
  123.                 dat.cga = vidseg;            /* color */
  124.             *(PATCH far*)MK_FP( rr.ds_, rr.dx_ + OFFSET ) = dat;
  125.         }
  126.         else
  127.             SE_STRC( "\aWRONG BOYAN VERSION\r\n" );
  128.         SETVECT( DOSINT, dosvec );        /* restore DOS interrupt vector */
  129.     }
  130. }
  131.  
  132. int pascal GETMOD( void )                /* GET VIDEO MODE */
  133. {
  134.     struct REGPACK r;
  135.     RHI( r.r_ax ) = GETVIDMOD;
  136.     intr( BIOSVID, &r );
  137.     return RLO( r.r_ax );
  138. }
  139.  
  140. unsigned pascal GETSEG( int mod )        /* GET TOPVIEW VIDEO BUFFER */
  141. {
  142.     struct REGPACK r;
  143.     r.r_es = mod == MONOTXT ? MDASEG : CGASEG ;    /* segment */
  144.     r.r_di = 0;                                    /* offset */
  145.     RHI( r.r_ax ) = GETVIDBUF;
  146.     intr( BIOSVID, &r );
  147.     if ( r.r_di & 15 ) {
  148.         SE_STRC( "\aVIDEO BUFFER BOUNDARY ERROR\r\n" );
  149.         exit( -1 );
  150.     }
  151.     return r.r_es + ( r.r_di >> 4 );
  152. }
  153.  
  154. main( int ac, char **av )
  155. {
  156.     int ret;
  157.     SE_STRC( banner );
  158.     if ( ac < 2 ) {
  159.         SE_STRC( "usage: pathname [arg...]\r\n" );
  160.         return -1;
  161.     }
  162.     vidseg = GETSEG( vidmod = GETMOD() );    /* get video segment */
  163.     dosvec = GETVECT( DOSINT );            /* save DOS interrupt vector */
  164.     SETVECT( DOSINT, intentry );        /* setup my interrupt vector */
  165.     if ( (ret = spawnv(P_WAIT, av[1], av + 1) ) == -1 )
  166.         SE_STRC( "\aCANNOT RUN PROGRAM\r\n" );
  167.     SETVECT( DOSINT, dosvec );            /* restore DOS interrupt vector */
  168.     return ret;
  169. }
  170.